﻿using System;
using Board;
using player;
using State;

namespace Game
{
    public class TttGame
    {
        private static TttBoard _board;
        private static TttPlayer _playerX;
        private static TttPlayer _playerO;

        public static TttPlayer PlayerX { get { return _playerX; } set { _playerX = value; } }
        public static TttPlayer PlayerO { get { return _playerO; } set { _playerO = value; } }

        public static string GameState 
        {
            get {
                return (_board == null) || (_playerX == null) || (_playerO == null)
                           ? null
                           : TttState.GameOver
                                ? Convert.ToInt32(TttState.WhoTurn).ToString() + " 000000000 " + _playerX.Score + ' ' + _playerO.Score
                                : Convert.ToInt32(TttState.WhoTurn).ToString() + ' ' + _board + ' ' + _playerX.Score + ' ' + _playerO.Score;
            }

            set
            {
                var strings = value.Split(' ');
                if (strings.Length != 4)
                    return;
                _board = null;
                _playerX = null;
                _playerO = null;
                TttState.WhoTurn = (PlayerTurn)Convert.ToInt32(strings[0]);
                _board = new TttBoard(strings[1]);
                _playerX = new TttPlayer("X", false, Convert.ToInt32(strings[2]));
                _playerO = new TttPlayer("O", false, Convert.ToInt32(strings[3]));
            }
        }

        /// <summary>
        /// This initializes the Players turn.  It will set the state
        /// to either X or O depending on whos turn it currently is.
        /// </summary>
        /// <returns>Which players turn it is</returns>
        public static PlayerTurn Initialize()
        {
            _board = new TttBoard();

            _playerX = new TttPlayer("X", false, 0);
            _playerO = new TttPlayer("O", false, 0);

            var random = new Random(DateTime.UtcNow.Millisecond);

            TttState.WhoTurn = (PlayerTurn)random.Next(1, 3);

            TttState.GameOver = false;

            return TttState.WhoTurn;
        }

        /// <summary>
        /// This will update the Tile with either X or O 
        /// depending on which players turn it is.
        /// </summary>
        /// <param name="position">The passed in Tile Position(1-9)</param>
        /// <returns>A string of either X or O depending on which players turn it is</returns>
        public static string UpdateTile(int position)
        {
            if (!TttState.GameOver)
            {
                var retVal = _board.UpdateTile(TttState.WhoTurn, position);

                if (retVal.State != TileState.Empty)
                    return retVal.State == TileState.O ? "O" : "X";

                return "ERROR";
            }

            // Something went wrong
            return "ERROR";
        }

        /// <summary>
        /// This checks who has won the game or if a draw has happened.
        /// </summary>
        /// <returns>An array that holds the values of who won</returns>
        public static int[] CheckWin()
        {
            var retVal = _board.CheckWinner((TileState)TttState.WhoTurn);

            if ((retVal == null) || (retVal[0] != 0))
            {
                TttState.GameOver = true;

                if (retVal != null) // not a draw
                {
                    if (TttState.WhoTurn == PlayerTurn.O)
                        _playerO.Score++;
                    else
                        _playerX.Score++;
                }
            }
            else
                TttState.WhoTurn = TttState.WhoTurn == PlayerTurn.O ? PlayerTurn.X : PlayerTurn.O; // only update turn if not a win/draw

            return retVal;
        }

        /// <summary>
        /// This will handle reseting the board and the
        /// players scores.
        /// </summary>
        public static void Reset()
        {
            NewGame();
            _playerO.Score = 0;
            _playerX.Score = 0;
        }

        /// <summary>
        /// This will initialize a new game clearing the board
        /// and players scores.
        /// </summary>
        public static void NewGame()
        {
            _board = null;
            _board = new TttBoard();
            TttState.GameOver = false;
        }
    }
}
